home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
ms_dos
/
dsort
/
dstqsrt.asm
< prev
next >
Wrap
Assembly Source File
|
1993-07-08
|
7KB
|
232 lines
page 96,132
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
;§ §
;§ ディレクトリエントリ ソート ユーティリティ §
;§ §
;§ DSORT.EXE Ver1.30 §
;§ §
;§ Copyright (C) by 福地 邦雄 1991-1992. All rights reserved. §
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
.MODEL SMALL,C
;
REVERSE equ 1
FALSE equ 0
direntrysize equ 20h
direntryseg equ 2
;
public dirqsort,dirswap,sortfuncall
;
.code
;
;------------------------------------------------------------------------------
;
; dirqsort
; ディレクトリエントリのクイックソート
;
; TYPE near call
; IN [SP+2] = ソートバッファセグメント
; [SP+4] = 要素数
; ES:[SP+6] = 比較関数リストアドレス
; OUT なし
; 保存レジスタ bp,ds
;
;------------------------------------------------------------------------------
;
dirqsort proc sortobj,elmcount,funclist
local cmpobj,chgedobj,cmpcount,chgcount,funcseg
;
mov funcseg,es
qsorthead:
cmp elmcount,1
; @if (zf,off),and,(cf,off),L ; 要素数2以上ならソート実行
jz @i0001
jnc @i0002
@i0001:
jmp @i0003
@i0002:
mov dx,sortobj
add dx,direntryseg
cmp elmcount,02
mov cmpobj,dx
; @if (zf,on) ; 要素数2なら直接比較
jnz @i0004
mov bx,funclist
mov es,funcseg
mov ds,sortobj
call sortfuncall
test ax,ax
; @if (zf,off),and,(sf,off) ; エントリ1が大きい時は入れ換え
jz @i0005
js @i0005
mov es,cmpobj
mov ds,sortobj
call dirswap
; @ifend
@i0005:
; @else ; 要素数3以上
jmp @i0006
@i0004:
mov ax,elmcount ; 比較の基準を配列の真ん中から取り出す
and ax,0fffeh
add ax,sortobj
mov es,ax
mov ds,sortobj
call dirswap
mov ax,sortobj ; 準備
mov chgcount,0
mov cmpcount,1
mov chgedobj,ax
; @do repeat
@d0001:
mov ax,cmpcount ; 比較終了か?
; @if (ax,>=,elmcount)
cmp ax,elmcount
jb @i0007
; @doexit
jmp @d0002
; @ifend
@i0007:
mov dx,sortobj ; 比較関数呼び出し
mov ds,cmpobj
mov bx,funclist
mov es,funcseg
call sortfuncall
test ax,ax
; @if (sf,on) ; 比較対象エントリが小さい時
jns @i0008
inc chgcount
add chgedobj,direntryseg
mov si,cmpobj
mov es,si
mov di,chgedobj
mov ds,di
; @if (si,/=,di)
cmp si,di
je @i0009
call dirswap
; @ifend
@i0009:
; @ifend
@i0008:
add cmpobj,direntryseg ; 次の比較対象へ
inc cmpcount
; @doend
jmp @d0001
@d0002:
mov di,sortobj ;
mov ds,di
mov si,chgedobj
mov es,si
; @if (si,/=,di)
cmp si,di
je @i0010
call dirswap
; @ifend
@i0010:
mov bx,chgedobj ; 再帰呼び出し準備
add bx,direntryseg
mov cx,elmcount
mov ax,chgcount
sub cx,ax
dec cx
; @if (cx,>,ax),S ; エントリ数の少ない方によって環境を整える
cmp cx,ax
jbe @i0011
mov elmcount,cx ; 入れ換え済の方が少ない
mov cx,ax
xchg bx,sortobj
; @else
jmp short @i0012
@i0011:
mov elmcount,ax ; 入れ換え無しの方が少ない
; @ifend
@i0012:
; @if (cx,>,1) ; 要素数2以上なら
cmp cx,1
jbe @i0013
mov es,funcseg ;
push funclist ; 再帰呼び出し(エントリの少ない方)
push cx
push bx
call dirqsort
; @ifend
@i0013:
jmp qsorthead ; 末尾再帰呼び出し(ループ)
; @ifend
@i0006:
; @ifend
@i0003:
ret 6
;
dirqsort endp
;
;------------------------------------------------------------------------------
;
; dirswap
; ディレクトリエントリの交換
;
; TYPE near call
; IN DS:0 = エントリ1アドレス
; ES:0 = エントリ2アドレス
; OUT なし
; 保存レジスタ bx,dx,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
dirswap proc
;
mov cx,direntrysize/2
xor si,si
swaploop:
mov ax,[si]
xchg es:[si],ax
mov [si],ax
lea si,[si+2]
loop swaploop
;
ret
;
dirswap endp
;
;------------------------------------------------------------------------------
;
; sortfuncall
; ソート用比較関数列の呼び出し
;
; TYPE near call
; IN ES:BX = 比較関数列のアドレス
; DS:0 = エントリ1アドレス
; DX:0 = エントリ2アドレス
; OUT AX = 比較結果
; 保存レジスタ si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
sortfuncall proc
;
; @do until
@d0003:
call word ptr es:[bx] ; 比較関数呼び出し
; @if (word ptr es:[bx+2],=,REVERSE) ; 逆順指定の時は結果を反転
cmp word ptr es:[bx+2],REVERSE
jne @i0014
neg ax
; @ifend
@i0014:
; @if (ax,/=,0) ; 比較して違いがあれば終了
or ax,ax
je @i0015
jmp compareend
; @ifend
@i0015:
lea bx,[bx+4] ; 次の比較関数へ
; @doend (word ptr es:[bx],=,0) ; 関数列の終了まで
cmp word ptr es:[bx],0
jne @d0003
compareend:
ret
;
sortfuncall endp
;
end